/**
 * 
 */
package com.nari.heatshare.dao;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Transformer;
import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import com.nari.coreframe.dao.hibernate3.GenericDaoImpl;
import com.nari.heatshare.model.IAssignMeter;
import com.nari.platform.model.PageCond;
import com.nari.platform.model.ResultWithPageCond;
import com.nari.rescontroller.dao.IResourceAccessControlDao;

/**
 * 
 * @author Xiaopeng
 * @date 2013-8-18
 */
public class AssignMeterDaoImpl extends GenericDaoImpl<IAssignMeter, String> 
		implements IAssignMeterDao {
	private IResourceAccessControlDao iResourceAccessControlDao;

	/**
	 * 分页查询分配表列表
	 * @param seriousNum 分配表表号(可选)
	 * @param projectUID 所属项目(可选)
	 * @param communityUID 所属小区(可选)
	 * @param buildingUID 所属楼栋(可选)
	 * @param roomUID 所属热用户(可选)
	 * @param pageCond
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-29
	 */
	@SuppressWarnings("unchecked")
	public ResultWithPageCond<IAssignMeter> queryAssignMeterPage(String seriousNum, 
			String projectUID, String communityUID, String buildingUID, String roomUID, 
			PageCond pageCond) throws Exception {
		Criteria listCriteria = this.getCurrentSession().createCriteria(IAssignMeter.class);
		Criteria countCriteria = this.getCurrentSession().createCriteria(IAssignMeter.class);
		//分配表表号
		if (seriousNum!=null && !"".equals(seriousNum.trim())) {
			listCriteria.add(Restrictions.ilike("seriousNum", seriousNum.trim().toLowerCase(), MatchMode.ANYWHERE));
			countCriteria.add(Restrictions.ilike("seriousNum", seriousNum.trim().toLowerCase(), MatchMode.ANYWHERE));
		}
		//所属项目
		if (projectUID!=null && !"".equals(projectUID.trim())) {
			listCriteria.add(Restrictions.eq("projectID", projectUID.trim()));
			countCriteria.add(Restrictions.eq("projectID", projectUID.trim()));
		}
		//所属小区
		if (communityUID!=null && !"".equals(communityUID.trim())) {
			listCriteria.add(Restrictions.eq("communityID", communityUID.trim()));
			countCriteria.add(Restrictions.eq("communityID", communityUID.trim()));
		}
		//所属楼栋
		if (buildingUID!=null && !"".equals(buildingUID.trim())) {
			listCriteria.add(Restrictions.eq("buildingID", buildingUID.trim()));
			countCriteria.add(Restrictions.eq("buildingID", buildingUID.trim()));
		}
		//所属热用户
		if (roomUID!=null && !"".equals(roomUID.trim())) {
			listCriteria.add(Restrictions.eq("roomId", roomUID.trim()));
			countCriteria.add(Restrictions.eq("roomId", roomUID.trim()));
		}
		//权限资源匹配
		String authorityRes = iResourceAccessControlDao.queryAuthorityProjResSql();
		if(!"".equals(authorityRes)) {
			//这是一个直接与底层数据库耦合的查询，注意避免数模更改带来的系统问题
			listCriteria.add(Restrictions.sqlRestriction("{alias}.t_project_id in("+authorityRes+")"));
			countCriteria.add(Restrictions.sqlRestriction("{alias}.t_project_id in("+authorityRes+")"));
		}
		//统计结果集个数
		int total = ((Long)countCriteria.setProjection(Projections.rowCount()).list().get(0)).intValue();
		//结果集排序
		listCriteria.addOrder(Order.asc("seriousNum")).addOrder(Order.asc("installDate"));
		//结果集分页
		listCriteria.setFirstResult(pageCond.getStart()).setMaxResults(pageCond.getLimit());
		//构造返回类型
		pageCond.setTotal(total);
		ResultWithPageCond<IAssignMeter> meterPage = new ResultWithPageCond<IAssignMeter>();
		meterPage.setList(listCriteria.list());
		meterPage.setPageCond(pageCond);
		return meterPage;
	}
	
	@Override
	public ArrayList<String> queryAssignMeterNo(String seriousNum, 
			String projectUID, String communityUID, String buildingUID, String roomUID) throws Exception{
		ArrayList<String> seriousNo = new ArrayList<String>();
//		Criteria listCriteria = this.getCurrentSession().createCriteria(IAssignMeter.class);
//		Criteria countCriteria = this.getCurrentSession().createCriteria(IAssignMeter.class);
		Criteria listCriteria = this.getSession().createCriteria(IAssignMeter.class);
		Criteria countCriteria = this.getSession().createCriteria(IAssignMeter.class);
		//分配表表号
		if (seriousNum!=null && !"".equals(seriousNum.trim())) {
			listCriteria.add(Restrictions.ilike("seriousNum", seriousNum.trim().toLowerCase(), MatchMode.ANYWHERE));
			countCriteria.add(Restrictions.ilike("seriousNum", seriousNum.trim().toLowerCase(), MatchMode.ANYWHERE));
		}
		//所属项目
		if (projectUID!=null && !"".equals(projectUID.trim())) {
			listCriteria.add(Restrictions.eq("projectID", projectUID.trim()));
			countCriteria.add(Restrictions.eq("projectID", projectUID.trim()));
		}
		//所属小区
		if (communityUID!=null && !"".equals(communityUID.trim())) {
			listCriteria.add(Restrictions.eq("communityID", communityUID.trim()));
			countCriteria.add(Restrictions.eq("communityID", communityUID.trim()));
		}
		//所属楼栋
		if (buildingUID!=null && !"".equals(buildingUID.trim())) {
			listCriteria.add(Restrictions.eq("buildingID", buildingUID.trim()));
			countCriteria.add(Restrictions.eq("buildingID", buildingUID.trim()));
		}
		//所属热用户
		if (roomUID!=null && !"".equals(roomUID.trim())) {
			listCriteria.add(Restrictions.eq("roomId", roomUID.trim()));
			countCriteria.add(Restrictions.eq("roomId", roomUID.trim()));
		}
		//该处不启用
		//权限资源匹配
//		String authorityRes = iResourceAccessControlDao.queryAuthorityProjResSql();
//		if(!"".equals(authorityRes)) {
//			//这是一个直接与底层数据库耦合的查询，注意避免数模更改带来的系统问题
//			listCriteria.add(Restrictions.sqlRestriction("{alias}.t_project_id in("+authorityRes+")"));
//			countCriteria.add(Restrictions.sqlRestriction("{alias}.t_project_id in("+authorityRes+")"));
//		}
		//结果集排序
		listCriteria.addOrder(Order.asc("seriousNum")).addOrder(Order.asc("installDate"));
		//结果集分页
		//构造返回类型
		List<IAssignMeter> list = listCriteria.list();
		seriousNo = (ArrayList<String>) CollectionUtils.collect(list, new Transformer() {
			@Override
			public Object transform(Object input) {
				IAssignMeter meter = (IAssignMeter) input;
				return meter.getSeriousNum();
			}
		});
		return seriousNo;
	}
	
	/**
	 * 通过所属关系查询分配表列表
	 * @param projectUID 所属项目(可选)
	 * @param communityUID 所属小区(可选)
	 * @param buildingUID 所属楼栋(可选)
	 * @param roomUID 所属热用户(可选)
	 * @return 若所属关系均不存在，则返回空列表
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-29
	 */
	@SuppressWarnings("unchecked")
	public List<IAssignMeter> queryAssignMetersByBelongs(String projectUID, String communityUID, 
			String buildingUID, String roomUID) throws Exception {
		Criteria listCriteria = this.getCurrentSession().createCriteria(IAssignMeter.class);
		if((projectUID!=null && !"".equals(projectUID)) 
				|| (communityUID!=null && !"".equals(communityUID)) 
				|| (buildingUID!=null && !"".equals(buildingUID)) 
				|| (roomUID!=null && !"".equals(roomUID))) {
			//所属项目
			if (projectUID!=null && !"".equals(projectUID.trim())) {
				listCriteria.add(Restrictions.eq("projectID", projectUID.trim()));
			}
			//所属小区
			if (communityUID!=null && !"".equals(communityUID.trim())) {
				listCriteria.add(Restrictions.eq("communityID", communityUID.trim()));
			}
			//所属楼栋
			if (buildingUID!=null && !"".equals(buildingUID.trim())) {
				listCriteria.add(Restrictions.eq("buildingID", buildingUID.trim()));
			}
			//所属热用户
			if (roomUID!=null && !"".equals(roomUID.trim())) {
				listCriteria.add(Restrictions.eq("roomId", roomUID.trim()));
			}
			//权限资源匹配
			String authorityRes = iResourceAccessControlDao.queryAuthorityProjResSql();
			if(!"".equals(authorityRes)) {
				//这是一个直接与底层数据库耦合的查询，注意避免数模更改带来的系统问题
				listCriteria.add(Restrictions.sqlRestriction("{alias}.t_project_id in("+authorityRes+")"));
			}
			//结果集排序
			listCriteria.addOrder(Order.asc("seriousNum")).addOrder(Order.asc("installDate"));
			return listCriteria.list();
		}
		return new ArrayList<IAssignMeter>();
	}
	
	/**
	 * 通过分配表表号查询分配表实体
	 * @param seriousNum
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-9-2
	 */
	public IAssignMeter queryMeterBySeriousNum(String seriousNum) throws Exception {
		String hsql = "from IAssignMeter am " +
				"where am.seriousNum='"+seriousNum+"'";
		List<IAssignMeter> meterList = this.runQueryHSql(hsql);
		IAssignMeter assignMeter = null;
		if(meterList!=null && meterList.size()>0) {
			assignMeter = meterList.get(0);
		}
		return assignMeter;
	}
	
	/**
	 * 根据所属热用户信息查询分配表列表
	 * @param seriousNum 分配表表号(可选)
	 * @param projectUID 所属项目(可选)
	 * @param communityUID 所属小区(可选)
	 * @param buildingUID 所属楼栋(可选)
	 * @param heatRoomUID 所属热用户(必填)
	 * 说明：若热用户ID不存在，则返回零结果集
	 * @param pageCond
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-9-4
	 */
	@SuppressWarnings("unchecked")
	public ResultWithPageCond<IAssignMeter> queryMeterPageByRoomUID(String seriousNum, 
			String projectUID, String communityUID, String buildingUID, String heatRoomUID, 
			PageCond pageCond) throws Exception {
		List<IAssignMeter> assignMeterList = new ArrayList<IAssignMeter>();
		int total = 0;
		//热用户存在时，分页查询热量表列表
		if(heatRoomUID!=null && !"".equals(heatRoomUID.trim())) {
			Criteria listCriteria = this.getCurrentSession().createCriteria(IAssignMeter.class);
			Criteria countCriteria = this.getCurrentSession().createCriteria(IAssignMeter.class);
			//所属热用户
			listCriteria.add(Restrictions.eq("roomId", heatRoomUID.trim()));
			countCriteria.add(Restrictions.eq("roomId", heatRoomUID.trim()));
			//分配表表号
			if (seriousNum!=null && !"".equals(seriousNum.trim())) {
				listCriteria.add(Restrictions.ilike("seriousNum", seriousNum.trim().toLowerCase(), MatchMode.ANYWHERE));
				countCriteria.add(Restrictions.ilike("seriousNum", seriousNum.trim().toLowerCase(), MatchMode.ANYWHERE));
			}
			//所属项目
			if (projectUID!=null && !"".equals(projectUID.trim())) {
				listCriteria.add(Restrictions.eq("projectID", projectUID.trim()));
				countCriteria.add(Restrictions.eq("projectID", projectUID.trim()));
			}
			//所属小区
			if (communityUID!=null && !"".equals(communityUID.trim())) {
				listCriteria.add(Restrictions.eq("communityID", communityUID.trim()));
				countCriteria.add(Restrictions.eq("communityID", communityUID.trim()));
			}
			//所属楼栋
			if (buildingUID!=null && !"".equals(buildingUID.trim())) {
				listCriteria.add(Restrictions.eq("buildingID", buildingUID.trim()));
				countCriteria.add(Restrictions.eq("buildingID", buildingUID.trim()));
			}
			//统计结果集个数
			total = ((Long)countCriteria.setProjection(Projections.rowCount()).list().get(0)).intValue();
			//结果集排序
			listCriteria.addOrder(Order.asc("seriousNum")).addOrder(Order.asc("installDate"));
			//结果集分页
			listCriteria.setFirstResult(pageCond.getStart()).setMaxResults(pageCond.getLimit());
			assignMeterList = listCriteria.list();
		}
		//构造返回类型
		pageCond.setTotal(total);
		ResultWithPageCond<IAssignMeter> meterPage = new ResultWithPageCond<IAssignMeter>();
		meterPage.setList(assignMeterList);
		meterPage.setPageCond(pageCond);
		return meterPage;
	}
	
	/**
	 * 通过分摊域唯一标识统计分配表的个数
	 * @param shareAreaUID 分摊域唯一标识(必填)
	 * @param ifMeasureCharge 是否参与计量收费
	 * 说明：1:不参与		2:参与
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-10-4
	 */
	public long countMeterNumByAreaUID(String shareAreaUID, 
			Integer ifMeasureCharge) throws Exception {
		//查询热用户
		String roomQuery = "select hr.id from IHeatRoom hr " +
				"where hr.shareAreaID='"+shareAreaUID+"'";
		if(ifMeasureCharge != null) {
			roomQuery += " and hr.ifMeasureCharge="+ifMeasureCharge;
		}
		//统计热用户所属的分配表个数
		String hsql = "select count(*) from IAssignMeter am " +
				"where am.roomId in("+ roomQuery +")";
		return (Long)this.getCurrentSession().createQuery(hsql).uniqueResult();
	}
	
	/**
	 * 根据散热器唯一标识查询与其一一对应的分配表信息
	 * @param heatSinkID
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-10-6
	 */
	public IAssignMeter queryMeterBySinkUID(String heatSinkID) throws Exception {
		IAssignMeter assignMeter = null;
		String hsql = "from IAssignMeter am " +
				"where am.heatSinkID='"+heatSinkID+"'";
		List<IAssignMeter> meterList = this.runQueryHSql(hsql);
		if(meterList!=null && meterList.size()>0) {
			assignMeter = meterList.get(0);
		}
		return assignMeter;
	}
	
	/**
	 * 通过所属关系统计分配表的个数
	 * @param projectUID 所属项目(可选)
	 * @param communityUID 所属小区(可选)
	 * @param buildingUID 所属楼栋(可选)
	 * @param roomUID 所属热用户(可选)
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-10-23
	 */
	public int countMeterSumByBelongs(String projectUID, String communityUID, 
			String buildingUID, String roomUID) throws Exception {
		Criteria countCriteria = this.getCurrentSession().createCriteria(IAssignMeter.class);
		//所属项目
		if (projectUID!=null && !"".equals(projectUID.trim())) {
			countCriteria.add(Restrictions.eq("projectID", projectUID.trim()));
		}
		//所属小区
		if (communityUID!=null && !"".equals(communityUID.trim())) {
			countCriteria.add(Restrictions.eq("communityID", communityUID.trim()));
		}
		//所属楼栋
		if (buildingUID!=null && !"".equals(buildingUID.trim())) {
			countCriteria.add(Restrictions.eq("buildingID", buildingUID.trim()));
		}
		//所属热用户
		if (roomUID!=null && !"".equals(roomUID.trim())) {
			countCriteria.add(Restrictions.eq("roomId", roomUID.trim()));
		}
		//权限资源匹配
		String authorityRes = iResourceAccessControlDao.queryAuthorityProjResSql();
		if(!"".equals(authorityRes)) {
			//这是一个直接与底层数据库耦合的查询，注意避免数模更改带来的系统问题
			countCriteria.add(Restrictions.sqlRestriction("{alias}.t_project_id in("+authorityRes+")"));
		}
		//统计结果集个数
		return ((Long)countCriteria.setProjection(Projections.rowCount()).list().get(0)).intValue();
	}
	
	/**
	 * 通过集中器号查询所属分配表个数
	 * @param concentratorNo
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-10-29
	 */
	public int countMeterSumByConcentratorNo(String concentratorNo) throws Exception {
		String concentratorQuery = "select con.id from IConcentrator con " +
				"where lower(con.concentratorNo)='"+concentratorNo.toLowerCase()+"'";
		String countQuery = "select count(*) from IAssignMeter am " +
				"where am.concentratorID in ("+concentratorQuery+")";
		return ((Long)this.runQueryHSqlObject(countQuery).get(0)).intValue();
	}
	
	/**
	 * 通过集中器唯一标识查询所属分配表个数
	 * @param concentratorUID
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-3-17
	 */
	public int countMeterSumByConcentratorID(String concentratorUID) throws Exception {
		String countQuery = "select count(*) from IAssignMeter am " +
				"where am.concentratorID='"+concentratorUID+"'";
		return ((Long)this.runQueryHSqlObject(countQuery).get(0)).intValue();
	}
	
	/**
	 * 通过分配表表号查询隶属于某一热用户的分配表
	 * @param seriousNum
	 * @param roomUID
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-1-22
	 */
	public IAssignMeter queryMeterInfoBySeriousNum(String seriousNum, String roomUID) throws Exception {
		String hsql = "from IAssignMeter am where am.seriousNum='"+seriousNum+"' " +
				"and am.roomId='"+roomUID+"'";
		List<IAssignMeter> meterList = this.runQueryHSql(hsql);
		//分配表信息
		IAssignMeter meter = null;
		if(meterList!=null && meterList.size()>0) {
			meter = meterList.get(0);
		}
		return meter;
	}
	
	/**
	 * 统计不隶属于某一热用户的分配表个数
	 * @param assignMeter
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-1-22
	 */
	public int countMeterNumBySeriousNum(String seriousNum, String roomUID) throws Exception {
		//统计不同用户中是否存在相同表号信息
		String meterCounterHql = "select count(*) from IAssignMeter am " +
				"where am.seriousNum='"+seriousNum+"' " +
				"and am.roomId<>'"+roomUID+"'";
		int counter = ((Long)this.getCurrentSession().createQuery(meterCounterHql).uniqueResult()).intValue();
		return counter;
	}
	
	/**
	 * 通过集中器唯一标识查询所属分配表列表
	 * @param concentratorUID
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-3-17
	 */
	public List<IAssignMeter> queryMetersByConcentratorID(String concentratorUID) throws Exception {
		String hsql = "from IAssignMeter am " +
				"where am.concentratorID='"+concentratorUID+"' " +
				"order by am.seriousNum asc";
		return this.runQueryHSql(hsql);
	}
	
	/**
	 * 统计相同分配表表号的分配表数量，避免系统录入相同分配表表号的分配表信息
	 * @param seriousNum
	 * @param assignMeterUID
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-7-28
	 */
	public int countBySeriousNum(String seriousNum, String assignMeterUID) throws Exception {
		String hsql = "select count(*) from IAssignMeter am " +
				"where am.seriousNum='"+seriousNum+"'";
		if(assignMeterUID!=null && !"".equals(assignMeterUID)) {
			hsql += " and am.id<>'"+assignMeterUID+"'";
		}
		return ((Long)this.getCurrentSession().createQuery(hsql).uniqueResult()).intValue();
	}

	/**
	 * @return the iResourceAccessControlDao
	 */
	public IResourceAccessControlDao getiResourceAccessControlDao() {
		return iResourceAccessControlDao;
	}

	/**
	 * @param iResourceAccessControlDao the iResourceAccessControlDao to set
	 */
	public void setiResourceAccessControlDao(
			IResourceAccessControlDao iResourceAccessControlDao) {
		this.iResourceAccessControlDao = iResourceAccessControlDao;
	}
	
}
